package com.ics.cmsadmin.modules.basic.service.impl;

import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.OrderStatusEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.frame.core.exception.ExceptionUtils;
import com.ics.cmsadmin.frame.utils.MathUtil;
import com.ics.cmsadmin.modules.agent.service.ShareDetailService;
import com.ics.cmsadmin.modules.basic.bean.OrderBean;
import com.ics.cmsadmin.modules.basic.service.OrderService;
import com.ics.cmsadmin.modules.basic.service.PayService;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.lly835.bestpay.utils.JsonUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * Created by Sandwich on 2018-08-18
 */
@Service
@Log4j2
public class PayServiceImpl implements PayService {

    private static final String ORDER_NAME = "course order";

    @Autowired
    private BestPayServiceImpl bestPayService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ShareDetailService shareDetailService;

    @Override
    public PayResponse create(OrderBean order) {
        PayRequest payRequest = new PayRequest();
        payRequest.setOpenid(order.getOpenId());
        payRequest.setOrderAmount(order.getOrderAmount().doubleValue());
        payRequest.setOrderId(order.getId());
        payRequest.setOrderName(ORDER_NAME);
        payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        log.info("【微信支付】发起支付, request={}", JsonUtil.toJson(payRequest));

        PayResponse payResponse = bestPayService.pay(payRequest);
        log.info("【微信支付】发起支付, response={}", JsonUtil.toJson(payResponse));
        return payResponse;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PayResponse orderNotify(String notifyData) {
        //1. 验证签名
        //2. 支付的状态
        //3. 支付金额
        //4. 支付人(下单人 == 支付人)

        PayResponse payResponse = bestPayService.asyncNotify(notifyData);
        log.info("【微信支付】异步通知, payResponse={}", JsonUtil.toJson(payResponse));

        //查询订单
        OrderBean order = orderService.queryById(payResponse.getOrderId());


        //判断订单是否存在
        if (order == null) {
            log.error("【微信支付】异步通知, 订单不存在, orderId={}", payResponse.getOrderId());
            throw new CmsException(ApiResultEnum.ORDER_NOT_EXIST);
        }

        //判断金额是否一致(0.10   0.1)
        if (!MathUtil.equals(payResponse.getOrderAmount(), order.getOrderAmount().doubleValue())) {
            log.error("【微信支付】异步通知, 订单金额不一致, orderId={}, 微信通知金额={}, 系统金额={}",
                    payResponse.getOrderId(),
                    payResponse.getOrderAmount(),
                    order.getOrderAmount());
            throw new CmsException(ApiResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
        }

        //修改订单的支付状态
        order.setStatus(OrderStatusEnum.SUCCESS.getCode());
        order.setPayTime(new Date(System.currentTimeMillis()));
        orderService.update(order);
        try {
            shareDetailService.generateShareByOrderId(payResponse.getOrderId());
        }catch (Exception e){
            log.error("订单{}分润入账异常{}", payResponse.getOrderId(), ExceptionUtils.collectExceptionStackMsg(e));
        }
        return payResponse;
    }

    /**
     * 退款
     * @param order
     */
    @Override
    public RefundResponse refund(OrderBean order) {
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setOrderId(order.getId());
        refundRequest.setOrderAmount(order.getOrderAmount().doubleValue());
        refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        log.info("【微信退款】request={}", JsonUtil.toJson(refundRequest));

        RefundResponse refundResponse = bestPayService.refund(refundRequest);
        log.info("【微信退款】response={}", JsonUtil.toJson(refundResponse));

        return refundResponse;
    }

}
